iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
1
Modern Web

今晚,我想來點Blazor系列 第 18

Day 18:樣板元件(2)

  • 分享至 

  • xImage
  •  

延續昨天的範例,我們將商品用bootstrap的Card Decks排列出來,現在我們有另一個model想用一樣的方式顯示,我們這時候可以將那樣的版面做成通用樣板元件。

首先我們先將版面改成下面這個樣子,有一個標題,一個<hr>標籤,一個Card Decks。
https://ithelp.ithome.com.tw/upload/images/20201002/20130058a9L0lY9ab0.jpg

接下來開始改造工作,首先將Card Decks裡的Card,獨立成一個Card元件。

<div class="card">
    <img class="card-img-top" src="@CardImgUrl" alt="Card image cap">
    <div class="card-body">
        <h5 class="card-title">@CardTitle</h5>
        <p class="card-text"><small class="text-muted">@CardSubTitle</small></p>
    </div>
</div>

@code{
    [Parameter]
    public string CardImgUrl { get; set; }

    [Parameter]
    public string CardTitle { get; set; }

    [Parameter]
    public string CardSubTitle { get; set; }
}

GenericCard template元件:

@typeparam TItem

<h3>@Title</h3>
<hr />

<div class="card-deck">
    @foreach (var item in Items)
    {
        @CardTemplate(item)
    }
</div>

@code {

    [Parameter]
    public RenderFragment Title { get; set; }

    [Parameter]
    public RenderFragment<TItem> CardTemplate { get; set; }

    [Parameter]
    public IReadOnlyList<TItem> Items { get; set; }
}
  • 加上@typeparam TItem,讓這個template可以接收泛型Parameter
  • IReadOnlyList<TItem> Items:接收要顯示的list資料
  • RenderFragment<TItem> CardTemplate:接收多個Card元件

Productlist改套用GenericCard template:

<GenericCard Items="products">
        <Title>
            <h2>Fruit</h2>
        </Title>
       <CardTemplate>
            <Card CardImgUrl="@context.ImgUrl" CardTitle="@context.ProductName" CardSubTitle="@context.Price.ToString("C")"></Card>
        </CardTemplate>
    </GenericCard>
  • 將products透過Items傳入GenericCard template
  • 可已透過context取得資料,並傳入Card元件
  • 如果覺得@context不夠明確,可以在CardTemplate標籤,或是GenericCard標籤中重新命名context:
<GenericCard Items="products">
        <Title>
            <h2>Fruit</h2>
        </Title>
        <CardTemplate Context="product">
            <Card CardImgUrl="@product.ImgUrl" CardTitle="@product.ProductName" CardSubTitle="@product.Price.ToString()"></Card>
        </CardTemplate>
    </GenericCard>
<GenericCard Items="products" Context="product">
        <Title>
            <h2>Fruit</h2>
        </Title>
        <CardTemplate>
            <Card CardImgUrl="@product.ImgUrl" CardTitle="@product.ProductName" CardSubTitle="@product.Price.ToString()"></Card>
        </CardTemplate>
    </GenericCard>

最後,我們製作一個SuperHeroes元件,準備好資料後,就可以套用GenericCard template啦

@if (heroes.Count == 0)
{
    <img src="https://media.giphy.com/media/3oEjI6SIIHBdRxXI40/giphy.gif" />
}
else
{
    <GenericCard Items="heroes">
        <Title>
            <h2 class="text-primary">Super Heroes</h2>
        </Title>
        <CardTemplate Context="hero">
            <Card CardImgUrl="@hero.ImgUrl" CardTitle="@hero.Name" CardSubTitle="@hero.RealName"></Card>
        </CardTemplate>
    </GenericCard>
}

@code {
    List<Hero> heroes = new List<Hero>();

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(1000);

        heroes.Add(new Hero() { Id = 1, Name = "Iron Man", ImgUrl = "https://terrigen-cdn-dev.marvel.com/content/prod/1x/002irm_ons_crd_03.jpg", RealName = "Tony Stark" });
        heroes.Add(new Hero() { Id = 1, Name = "Captain America", ImgUrl = "https://terrigen-cdn-dev.marvel.com/content/prod/1x/003cap_ons_crd_03.jpg", RealName = "Steve Rogers" });
        heroes.Add(new Hero() { Id = 1, Name = "Hulk", ImgUrl = "https://terrigen-cdn-dev.marvel.com/content/prod/1x/006hbb_ons_crd_03.jpg", RealName = "Bruce Banner" });

        base.OnInitialized();
    }
}

https://ithelp.ithome.com.tw/upload/images/20201002/20130058RtZBWQYcS7.jpg


上一篇
Day 17:樣板元件(1)
下一篇
Day 19:元件的事件處理
系列文
今晚,我想來點Blazor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言